﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;
using System.Threading;

namespace BDSim
{
    /// <summary>
    /// 用户段-轮船模型
    /// </summary>
    public class Ship : DynamicUser
    {
        #region 字段
        //public double TrackSimStep;//轨迹仿真步长，通过右键弹框赋值
        //public double TrackOutStep;//轨迹输出步长，通过右键弹框赋值

        //#region 存储数据
        //string directoryname;//轨迹数据文件夹名称，暂时存储过程数据
        //string ObsDatadirectoryname;//观测数据文件夹名称
        //string PVTDatadirectoryname;//定位数据文件夹名称
        //string TrackDataFilename;//轨迹数据文件的名称，暂时存储过程数据
        //string[] ObsDataFilename;//接收机观测数据文件的名称，暂时存储过程数据
        //string[] PVTDataFilename;//接收机定位数据文件的名称，暂时存储过程数据
        //#endregion 存储数据

        #endregion 字段

        public Ship()
        {
            Name = "船";
            Type = EUserType.Boat;
            DefineCommand();
        }

        #region 初始化
       
        #region 初始化中的函数

        /// <summary>
        /// 轨迹数据仿真
        /// </summary>
        public override void DynamicSim()
        {
            TrackSimStep = 1;//单位：s
            TrackOutStep = GlobalStepSize;//单位：s

            string configfile = SimTrackFileName + "simu";
            string limitfile = SimTrackFileName + "lim";

            if (null == SimTrackFileName)
            {
                MessageBox.Show("请配置轨迹动态！");
                Thread thd = Thread.CurrentThread;
                BDSimObject.GlobalStatus = ESimStatus.UnInited;
                thd.Abort();
            }

            AirTrackSimulationDLL.InitTrack(configfile.ToCharArray(), limitfile.ToCharArray(), TrackSimStep, TrackOutStep, 0, 1);

            #region 存储数据
            TrackDataFilename = directoryname + Name + "轨迹数据.txt";
            string trackdata;
            #endregion 存储数据

            UTCTime temp = BDSimObject.GlobalStartTime;
            int index = 0;
            NodePosVel userpv = new NodePosVel();
            Attitude userattitude = new Attitude();

            while (temp.Jd < BDSimObject.GlobalEndTime.Jd)
            {
                index++;
                temp.AddSecond(1);//轨迹数据每1s输出一组
                TimeSpaceDll.CAL2UTC(out temp, 1);

                OutPoint userdata = new OutPoint();
                AirExceptionMsg airexcpmsg = new AirExceptionMsg();


                if (1 == AirTrackSimulationDLL.GetOneData(out userdata, out airexcpmsg))
                {
                    userpv.epoch = temp;
                    userpv.X = userdata.x;
                    userpv.Y = userdata.y;
                    userpv.z = userdata.z;
                    userpv.vx = userdata.vx;
                    userpv.vy = userdata.vy;
                    userpv.vz = userdata.vz;

                    userattitude.Yaw = userdata.yaw;//姿态数据赋值
                    userattitude.Pitch = userdata.pitch;
                    userattitude.Roll = userdata.roll;

                    PosVelXYZList.Add(userpv);
                    AttitudeList.Add(userattitude);

                    #region 存储数据
                    trackdata = temp.Year.ToString() + " " + temp.mon.ToString().PadLeft(2) + " " + temp.Day.ToString().PadLeft(2) +
                                " " + temp.hour.ToString().PadLeft(2) + " " + temp.min.ToString().PadLeft(2) + " " + temp.sec.ToString().PadLeft(2) + " ";
                    trackdata += userpv.x.ToString() + " ";
                    trackdata += userpv.y.ToString() + " ";
                    trackdata += userpv.z.ToString() + " ";
                    trackdata += userpv.vx.ToString() + " ";
                    trackdata += userpv.vy.ToString() + " ";
                    trackdata += userpv.vz.ToString() + "\n";
                    File.AppendAllText(TrackDataFilename, trackdata);
                    #endregion 存储数据
                }
                else
                {
                    PosVelXYZList.Add(userpv);
                    AttitudeList.Add(userattitude);

                    #region 存储数据
                    trackdata = temp.Year.ToString() + " " + temp.mon.ToString().PadLeft(2) + " " + temp.Day.ToString().PadLeft(2) +
                                " " + temp.hour.ToString().PadLeft(2) + " " + temp.min.ToString().PadLeft(2) + " " + temp.sec.ToString().PadLeft(2) + " ";
                    trackdata += userpv.x.ToString() + " ";
                    trackdata += userpv.y.ToString() + " ";
                    trackdata += userpv.z.ToString() + " ";
                    trackdata += userpv.vx.ToString() + " ";
                    trackdata += userpv.vy.ToString() + " ";
                    trackdata += userpv.vz.ToString() + "\n";
                    File.AppendAllText(TrackDataFilename, trackdata);
                    #endregion 存储数据
                }
            }
            for (int i = 0; i < PosVelXYZList.Count; i++)
            {
                BLH_PosVel blh;
                TimeSpaceDll.XYZ2BLH(PosVelXYZList[i], ECFtype.type_CGCS2000, out blh);
                UserTrajectory.Add(new UserTrajectoryClass(blh, PosVelXYZList[i]));
            }
        }

        #endregion 初始化中的函数
        #endregion 初始化

        #region 单步运行
        public override void StepRun()
        {
            base.StepRun();

            #region 存储数据
            double nowTime = (BDSimObject.GlobalCurrentTime.Jd - BDSimObject.GlobalStartTime.Jd) * 86400.0;//当前系统运行时刻
            int timeID = (int)((nowTime + 0.001) / GlobalStepSize);
            PosVelXYZ = PosVelXYZList[timeID];//实时更新载体位置
            UserAttitude = AttitudeList[timeID];//实时更新载体姿态

            int id = -1;//接收机列表中的接收机序号
            string data1 = BDSimObject.GlobalCurrentTime.Year.ToString() + " " + BDSimObject.GlobalCurrentTime.mon.ToString().PadLeft(2) + " " + BDSimObject.GlobalCurrentTime.Day.ToString().PadLeft(2) +
                                " " + BDSimObject.GlobalCurrentTime.hour.ToString().PadLeft(2) + " " + BDSimObject.GlobalCurrentTime.min.ToString().PadLeft(2) + " " + BDSimObject.GlobalCurrentTime.sec.ToString("0.0").PadLeft(2) + " ";
            string data;
            #endregion 存储数据

            foreach (var item in RecCollection)
            {

                item.StepRun();
                FixedPosVelXYZ = item.FixedPosVelXYZ;

                #region 存储数据
                id++;
                //存储观测数据
                for (int i = 0; i < RecCollection[id].ObsSatsDataList.Count(); i++)
                {
                    data = data1 + RecCollection[id].ObsSatsDataList[i][0].SatID.ToString().PadLeft(2, ' ') + " ";
                    for (int j = 0; j < RecCollection[id].ObsSatsDataList[i].Count(); j++)//zly2022
                    {
                        data += RecCollection[id].ObsSatsDataList[i][j].SatObs.A_Pseudo_writein.ToString() + " ";
                        data += RecCollection[id].ObsSatsDataList[i][j].SatObs.A_Carri_writein.ToString() + " ";
                    }
                    data += "\n";

                    File.AppendAllText(ObsDataFilename[id], data);
                }

                //存储定位数据
                data = data1;
                data += FixedPosVelXYZ.x.ToString() + " ";
                data += FixedPosVelXYZ.y.ToString() + " ";
                data += FixedPosVelXYZ.z.ToString() + " ";
                data += (FixedPosVelXYZ.x - PosVelXYZ.x).ToString() + " ";
                data += (FixedPosVelXYZ.y - PosVelXYZ.y).ToString() + " ";
                data += (FixedPosVelXYZ.z - PosVelXYZ.z).ToString() + "\n";
                File.AppendAllText(PVTDataFilename[id], data);

                #endregion 存储数据
            }
        }
        #endregion

        #region 右键功能补充
        #region 命令定义
        MenuCommand DynamicSetCmd = new MenuCommand();
        #endregion 命令定义

        #region 命令定义初始化
        public void DefineCommand()
        {
            DynamicSetCmd.Header = "仿真轨迹动态设置";
            DynamicSetCmd.DefineExcuteCommand(DynamicParamSetFunc_Execute, DynamicParamSetFunc_CanExecute);
            this.DataProvider.MenuCommandList[1].SubMenuCommandList.Add(DynamicSetCmd);

        }
        #endregion 命令定义初始化

        #region 命令实现
        void DynamicParamSetFunc_Execute(object param)
        {
            AircraftDynamicSetWnd wndair = new AircraftDynamicSetWnd();
            wndair.AirViewModel.Parent = this;
            wndair.ShowDialog();

            SimTrackFileName = wndair.AirViewModel.SimTrackFileName;
        }

        bool DynamicParamSetFunc_CanExecute(object param)
        {
            bool flag = false;
            if (BDSimObject.GlobalStatus == ESimStatus.UnInited || BDSimObject.GlobalStatus == ESimStatus.End)
            {
                if (ETrackGenType.Simulation == TrackGenType)
                {
                    flag = true;
                }
            }
            return flag;
        }
        #endregion 命令实现

        #endregion 右键功能补充
    }
}
